#include "EpilIfStatementParser.h"
#include "EpilExpressionParser.h"
#include "EpilThenBlockParser.h"
#include "EpilChunkParser.h"
#include "EpilParserException.h"
#include "EpilPointerHelper.h"


EpilIfStatementParser::EpilIfStatementParser( EpilTokenStream & tokens )
: EpilSyntaxParserBase( tokens )
{
}


void EpilIfStatementParser::Parse()
{
	// ifstat -> IF expr THEN block {ELSEIF expr THEN block} [ELSE block] END
	m_statement = new EpilIfStatementCode( this->GetTokens().GetCurrentToken().location );

	EpilThenBlockParser ifParser( this->GetTokens() );
	try
	{
		ifParser.Parse();
	}
	catch( ... )
	{
		EpilPointerHelper::SafeDelete( m_statement );
		throw;
	}
	m_statement->SetIfBlock( ifParser.GetThenBlock() );

	while( this->GetTokens().GetCurrentToken().type == ETT_KwElseif )
	{
		EpilThenBlockParser elseifParser( this->GetTokens() );
		try
		{
			elseifParser.Parse();
		}
		catch( ... )
		{
			EpilPointerHelper::SafeDelete( m_statement );
			throw;
		}
		m_statement->GetElseIfBlocks().push_back( elseifParser.GetThenBlock() );
	}

	if( this->GetTokens().GetCurrentToken().type == ETT_KwElse )
	{
		this->GetTokens().MoveToNext();
		EpilChunkParser elseParser( this->GetTokens() );
		try
		{
			elseParser.Parse();
		}
		catch( ... )
		{
			EpilPointerHelper::SafeDelete( m_statement );
			throw;
		}
		m_statement->SetElseBlock( elseParser.GetChunk() );
	}
	else
	{
		m_statement->SetElseBlock( NULL );
	}

	if( this->GetTokens().GetCurrentToken().type != ETT_KwEnd )
	{
		EpilPointerHelper::SafeDelete( m_statement );
		throw EpilParserException( t("\'end\' expected."), this->GetTokens().GetCurrentToken().location );
	}
	this->GetTokens().MoveToNext();
}